home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / PostScript / Pencil / Source / PencilImage.m < prev    next >
Encoding:
Text File  |  1995-06-12  |  5.1 KB  |  218 lines

  1. /*
  2. Pencil V1.0, Copyright 1994, 95 by Florian Marquardt.
  3. This program may be distributed under the terms of the GNU general
  4. public license (Start Pencil and select "Info>COPYING..." for a copy of the
  5. license).
  6. */
  7. // changed 23_10_94: added save/restore for EPS-hack
  8. #import "PencilImage.h"
  9. #import <math.h>
  10.  
  11. extern BOOL globalOutlines;
  12. extern BOOL movementStatus;
  13. #define M_180_PI 180.0/M_PI
  14. extern void expandRect(NXRect *, float, float);
  15. #define TRANSFORMX(a,b) (tx+sx*cos(phi)*(a)-sy*sin(phi)*(b))
  16. #define TRANSFORMY(a,b) (ty+sx*sin(phi)*(a)+sy*cos(phi)*(b))
  17.  
  18. @implementation PencilImage
  19. - initFromFile:(const char *)filename
  20. {
  21.     [super init];
  22.     sx=sy=1;
  23.     transformed=NO;
  24.     if(theImage=[NXImage alloc])
  25.     {
  26.         [theImage setDataRetained:YES];
  27.         if([theImage  loadFromFile:filename])
  28.             return self;
  29.         else
  30.         {
  31.             [theImage free];
  32.             return nil;
  33.         }
  34.     }
  35.     else
  36.         return nil;
  37. }
  38.  
  39. - free
  40. {
  41.     if(theImage)    [theImage free];
  42.     return [super free];
  43. }
  44.  
  45. - (BOOL)selected:(NXEvent *)te:(int *)cp:(id)view
  46. {
  47.     NXPoint pt;
  48.     NXSize thesize;
  49.  
  50.     pt=te->location;
  51.     [self transformPoint:&pt];
  52.     [theImage getSize:&thesize];
  53.     if(pt.x>=0 && pt.y>=0 && pt.x<=thesize.width && pt.y<=thesize.height)
  54.         return(YES);
  55.     else
  56.         return(NO);
  57. }
  58.  
  59. - (BOOL)move:(NXEvent *)tte:(int *)cp:(id)view:(float)bsize
  60. {
  61.     return NO;
  62. }
  63.  
  64. - (void)draw:(NXRect *)re
  65. {
  66.     if(!re || NXIntersectsRect(&bounds, re))
  67.     {
  68.     if(globalOutlines)
  69.     {
  70.     NXSize thesize;
  71.     [theImage getSize:&thesize];
  72.     PSgsave();
  73.     if(translated)    PStranslate(tx,ty);
  74.     if(rotated)        PSrotate(M_180_PI*phi);
  75.     if(scaled)        PSscale(sx,sy);
  76.     PSsetlinewidth(0);
  77.     PSsetgray(.333);
  78.     PSrectstroke(0,0,thesize.width,thesize.height);
  79.     PSgrestore();
  80.     }
  81.     else
  82.     {
  83.     PSgsave();
  84.     if(translated)    PStranslate(tx,ty);
  85.     if(rotated)        PSrotate(M_180_PI*phi);
  86.     if(scaled)        PSscale(sx,sy);
  87.     if([[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])
  88.     {    // Sorry, we need this very UGLY hack, because
  89.         // we want rotated images and therefore we would
  90.         // need "draw", but unfortunately "draw" uses a
  91.         // different DPS context for EPS images (which results in wrong clipping), so...
  92.         char *theEPScode; int length;
  93.         char *thetext;
  94.         NXRect box;
  95.  
  96.         [[(NXEPSImageRep *)[theImage bestRepresentation] getBoundingBox:&box] getEPS:&theEPScode length:&length];
  97.         thetext=(char *)malloc(sizeof(char)*(length+1));
  98.         strncpy(thetext, theEPScode, length);
  99.         thetext[length]=0;
  100.         DPSPrintf(DPSGetCurrentContext(), "0 setgray 0 setlinewidth save %g %g translate\n%s\nrestore\n", -box.origin.x, -box.origin.y, thetext);
  101.         free(thetext);
  102.     }
  103.     else // we need "draw", since we want rotated tiff images, too
  104.         [[theImage bestRepresentation] draw];
  105.     PSgrestore();
  106.     }
  107.     }
  108. }
  109.  
  110. - (void)drawPath
  111. {
  112.     NXSize thesize;
  113.     [theImage getSize:&thesize];
  114.     DPSPrintf(DPSGetCurrentContext()," matrix currentmatrix ");
  115.     if(translated)    PStranslate(tx,ty);
  116.     if(rotated)        PSrotate(M_180_PI*phi);
  117.     if(scaled)        PSscale(sx,sy);
  118.     PSmoveto(0,0);
  119.     PSlineto(thesize.width,0);
  120.     PSlineto(thesize.width,thesize.height);
  121.     PSlineto(0, thesize.height);
  122.     PSclosepath();
  123.     DPSPrintf(DPSGetCurrentContext()," setmatrix\n");
  124. }
  125.  
  126. - calculateBoundingBox:(id)view
  127. {
  128.     float llx, lly, urx, ury;
  129.     NXSize thesize;
  130.  
  131.     [theImage getSize:&thesize];
  132.     llx=lly=0;
  133.     urx=thesize.width;
  134.     ury=thesize.height;
  135.     bounds.origin.x=TRANSFORMX(llx,lly);
  136.     bounds.origin.y=TRANSFORMY(llx,lly);
  137.     bounds.size.width=bounds.size.height=0;
  138.     expandRect(&bounds, TRANSFORMX(llx,ury),TRANSFORMY(llx,ury));
  139.     expandRect(&bounds, TRANSFORMX(urx,ury), TRANSFORMY(urx,ury));
  140.     expandRect(&bounds, TRANSFORMX(urx,lly),TRANSFORMY(urx,lly));
  141.     return self;
  142. }
  143.  
  144. - (void)drawControl:(NXRect *)re:(int)cp:(float)bsize
  145. {
  146.     NXSize thesize;
  147.  
  148.     [theImage getSize:&thesize];
  149.     if(!movementStatus || ![[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])
  150.         [self draw:re];
  151.     if(transformed)    {    PSgsave();
  152.     if(translated)    PStranslate(tx,ty);
  153.     if(rotated)        PSrotate(M_180_PI*phi);
  154.     if(scaled)        PSscale(sx,sy);
  155.     }
  156.     PSsetlinewidth(0);
  157. /*    if([[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])
  158.     {
  159.         PSsetgray(.5);
  160.         PSsetlinewidth(0);
  161.         PSmoveto(0,0); 
  162.         PSlineto(thesize.width,thesize.height);
  163.         PSstroke();
  164.         PSmoveto(thesize.width,0);
  165.         PSlineto(0,thesize.height);
  166.         PSstroke();
  167.     }
  168.     PSsetgray(.8);
  169.     PSrectstroke(2,2,thesize.width-4,thesize.height-4);
  170. */
  171.     PSsetrgbcolor(1,0,0);
  172.     PSsetlinewidth(2);
  173. #define WW thesize.width*.1
  174. #define HH thesize.height*.1
  175. #define HO (thesize.height-2)
  176. #define WO (thesize.width-2)
  177.     PSmoveto(WW+2,2);
  178.     PSrlineto(-WW,0);
  179.     PSrlineto(0, HH);
  180.     PSstroke();
  181.     PSmoveto(WW+2,HO);
  182.     PSrlineto(-WW,0);
  183.     PSrlineto(0,-HH);
  184.     PSstroke();
  185.     PSmoveto(WO-WW,2);
  186.     PSrlineto(WW,0);
  187.     PSrlineto(0,HH);
  188.     PSstroke();
  189.     PSmoveto(WO-WW,HO);
  190.     PSrlineto(WW,0);
  191.     PSrlineto(0,-HH);
  192.     PSstroke();
  193.     if(transformed)    PSgrestore();
  194. }
  195.  
  196. - (void)drawIfNeeded:(NXRect *)re:(int)cp:(float)bsize
  197. {     if([[theImage bestRepresentation] isKindOf:[NXEPSImageRep class]])         [self drawControl:re:cp:bsize];  }
  198. //  used for redrawing EPS after a move...
  199.  
  200. - write:(NXTypedStream *)stream
  201. {
  202.     [super write:stream];
  203.     NXWriteObject(stream,theImage);
  204.     return self;    
  205. }
  206.  
  207. - read:(NXTypedStream *)stream
  208. {
  209.     [super read:stream];
  210.     theImage=NXReadObject(stream);
  211.     return self;
  212. }
  213.  
  214. - (void)writeType:(NXStream *)to
  215. {
  216.     NXPrintf(to,"3");
  217. }
  218. @end